<?php

require_once( 'flexical/service/storage.php' );
require_once( 'flexical/service/lock.php' );
require_once( 'flexical/service/constants.php' );

require_once( 'flexical/model/feed.php' );
require_once( 'flexical/model/query.php' );
require_once( 'flexical/model/format.php' );
require_once( 'flexical/model/feed-query.php' );
require_once( 'flexical/model/listing.php' );

class Flexical_Service_DAO
{
	private $prefix;

	private $feeds_storage;
	private $queries_storage;
	private $formats_storage;
	private $feed_query_storage;
	private $listings_storage;

	private $lock;

	public function __construct()
	{
		$this->prefix = Flexical_Service_Constants::$OPTION_PREFIX;

		$this->feeds_storage = new Flexical_Service_Storage( 'feeds' );
		$this->queries_storage = new Flexical_Service_Storage( 'queries' );
		$this->formats_storage = new Flexical_Service_Storage( 'formats' );
		$this->feed_query_storage = new Flexical_Service_Storage( 'feed_query' );
		$this->listings_storage = new Flexical_Service_Storage( 'listings' );

		$this->lock = new Flexical_Service_Lock( 'dao' );
	}

	public function create_feed( $feed )
	{
		$this->lock->lock();
		$feed = $this->feeds_storage->create( $feed );
		$this->lock->unlock();

		return $feed;
	}

	public function read_feed( $id )
	{
		$this->lock->lock();
		$feed = $this->feeds_storage->read( $id );
		$this->lock->unlock();

		return $feed;
	}

	public function read_feeds()
	{
		$this->lock->lock();
		$feeds = $this->feeds_storage->read();
		$this->lock->unlock();

		return $feeds;
	}

	public function update_feed( $feed )
	{
		$this->lock->lock();
		$this->feeds_storage->update( $feed );
		$this->lock->unlock();
	}

	public function delete_feed( $id )
	{
		$this->lock->lock();
		$this->feeds_storage->delete( $id );
		$feed_queries = $this->feed_query_storage->read();

		foreach ( $feed_queries as $feed_query )
		{
			if ( $feed_query->feed_id == $id )
			{
				$this->feed_query_storage->delete( $feed_query->id );
			}
		}

		$this->lock->unlock();
	}

	public function create_query( $query )
	{
		$this->lock->lock();
		$query = $this->queries_storage->create( $query );
		$this->lock->unlock();

		return $query;
	}

	public function read_query( $id )
	{
		$this->lock->lock();
		$query = $this->queries_storage->read( $id );
		$this->lock->unlock();

		return $query;
	}

	public function read_queries()
	{
		$this->lock->lock();
		$queries = $this->queries_storage->read();
		$this->lock->unlock();

		return $queries;
	}

	public function update_query( $query )
	{
		$this->lock->lock();
		$this->queries_storage->update( $query );
		$this->lock->unlock();
	}

	public function delete_query( $id )
	{
		$this->lock->lock();
		$this->queries_storage->delete( $id );
		$feed_queries = $this->feed_query_storage->read();

		foreach ( $feed_queries as $feed_query )
		{
			if ( $feed_query->query_id == $id )
			{
				$this->feed_query_storage->delete( $feed_query->id );
			}
		}

		$this->lock->unlock();
	}

	public function create_format( $format )
	{
		$this->lock->lock();
		$format = $this->formats_storage->create( $format );
		$this->lock->unlock();

		return $format;
	}

	public function read_format( $id )
	{
		$this->lock->lock();
		$format = $this->formats_storage->read( $id );
		$this->lock->unlock();

		return $format;
	}

	public function read_formats()
	{
		$this->lock->lock();
		$formats = $this->formats_storage->read();
		$this->lock->unlock();

		return $formats;
	}

	public function update_format( $format )
	{
		$this->lock->lock();
		$formats = $this->formats_storage->update( $format );
		$this->lock->unlock();
	}

	public function delete_format( $id )
	{
		$this->lock->lock();
		$format = $this->formats_storage->delete( $id );
		$listings = $this->listings_storage->read();

		foreach ( $listings as $listing )
		{
			if ( $listing->format_id == $id )
			{
				$listing->format_id = -1;
				$this->listings_storage->update( $listing );
			}
		}

		$this->lock->unlock();
	}

	public function create_feed_query( $feed_query )
	{
		$this->lock->lock();
		$feed_query = $this->feed_query_storage->create( $feed_query );
		$this->lock->unlock();

		return $feed_query;
	}

	public function read_feed_query( $id )
	{
		$this->lock->lock();
		$feed_query = $this->feed_query_storage->read( $id );
		$this->lock->unlock();

		return $feed_query;
	}

	public function read_feed_queries()
	{
		$this->lock->lock();
		$feed_queries = $this->feed_query_storage->read();
		$this->lock->unlock();

		return $feed_queries;
	}

	public function update_feed_query( $feed_query )
	{
		$this->lock->lock();
		$feed_queries = $this->feed_query_storage->update( $feed_query );
		$this->lock->unlock();
	}

	public function delete_feed_query( $id )
	{
		$this->lock->lock();
		$feed_query = $this->feed_query_storage->delete( $id );
		$this->lock->unlock();
	}

	public function create_listing( $listing )
	{
		$this->lock->lock();
		$fq_list = array();

		$listing = $this->listings_storage->create( $listing );

		foreach ( $listing->feed_query_list as $feed_query )
		{
			$feed_query->listing_id = $listing->id;
			$feed_query = $this->feed_query_storage->create( $feed_query );
			$fq_list[ $feed_query->id ] = $feed_query;
		}

		$listing->feed_query_list = $fq_list;
		$listing = $this->listings_storage->update( $listing );
		$this->lock->unlock();

		return $listing;
	}

	public function read_listing( $id )
	{
		$this->lock->lock();
		$listing = $this->listings_storage->read( $id );

		if ( $listing != null )
		{
			$listing->feed_query_list = array();
			$feed_queries = $this->feed_query_storage->read();

			foreach ( $feed_queries as $feed_query )
			{
				if ( $feed_query->listing_id == $id )
				{
					$listing->feed_query_list[ $feed_query->id ] = $feed_query;
				}
			}
		}

		$this->lock->unlock();

		return $listing;
	}

	public function read_listings()
	{
		$this->lock->lock();
		$listings = $this->listings_storage->read();
		$feed_queries = $this->feed_query_storage->read();

		foreach ( $listings as $l_index => $listing )
		{
			$listing->feed_query_list = array();
		}

		foreach ( $feed_queries as $fq_index => $feed_query )
		{
			if ( isset( $listings[ $feed_query->listing_id ] ) )
			{
				$listings[ $feed_query->listing_id ]->feed_query_list[ $feed_query->id ] = $feed_query;
			}
		}

		$this->lock->unlock();

		return $listings;
	}

	public function update_listing( $listing )
	{
		$this->lock->lock();

		$old_listing = $this->listings_storage->read( $listing->id );

		if ( $old_listing == null )
		{
			return;
		}

		$old_fqs = array();

		foreach ( $this->feed_query_storage->read() as $feed_query )
		{
			if ( $feed_query->listing_id == $listing->id )
			{
				$old_fqs[ $feed_query->id ] = $feed_query;
			}
		}

		$updated_fqs = array();
		$new_fqs = array();

		foreach ( $listing->feed_query_list as $feed_query )
		{
			if ( $feed_query->id != -1 )
			{
				$updated_fqs[ $feed_query->id ] = $feed_query;
			}

			else
			{
				$new_fqs[] = $feed_query;
			}
		}

		foreach ( $old_fqs as $old_fq )
		{
			if ( isset( $updated_fqs[ $old_fq->id ] ) )
			{
				$this->feed_query_storage->update( $updated_fqs[ $old_fq->id ] );
			}

			else
			{
				$this->feed_query_storage->delete( $old_fq->id );
			}
		}

		foreach ( $new_fqs as $new_fq )
		{
			$new_fq->listing_id = $listing->id;
			$new_fq = $this->feed_query_storage->create( $new_fq );
		}

		$this->listings_storage->update( $listing );

		$this->lock->unlock();
	}

	public function delete_listing( $id )
	{
		$this->lock->lock();
		$listing = $this->listings_storage->delete( $id );

		$feed_queries = $this->feed_query_storage->read();

		foreach ( $feed_queries as $feed_query )
		{
			if ( $feed_query->listing_id == $id )
			{
				$this->feed_query_storage->delete( $feed_query->id );
			}
		}

		$this->lock->unlock();
	}

	public function install_data()
	{
		$this->feeds_storage->install();
		$this->queries_storage->install();
		$this->feed_query_storage->install();
		$this->formats_storage->install();
		$this->listings_storage->install();
	}

	public function uninstall_data()
	{
		$this->feeds_storage->uninstall();
		$this->queries_storage->uninstall();
		$this->feed_query_storage->uninstall();
		$this->formats_storage->uninstall();
		$this->listings_storage->uninstall();
	}
}

?>
